<script setup lang="ts">
import { ref } from "vue";
import AddRemoveList from "./Transition/AddRemoveList.vue";
import { BizhiDataMark, BizhiDataType } from "@/common/storage-mark";
import { sendMessage } from "./utils/message";
import { Camera } from "@element-plus/icons-vue";
import * as wxt from "wxt/storage";
import { convartBgURL, defaultBgUrl } from "@/common";

/** 壁纸预览状态 */
const bizhiPreviewStatus = ref(false);
/** 是否显示 壁纸 swapper  */
const showBizhiSwiper = ref(false); // 默认：不显示
/** 当前壁纸索引 */
const bizhiIndex = ref(0);
/** 壁纸地址前缀 */
const bizhiUrlPrefix = "/images/bizhi";
/** 当前壁纸Url */
const bizhiUrl = ref("");
/** 自带的所有壁纸Url */
const systemBizhiUrls = reactive([]) as string[];
/** 用户自定义壁纸Url */
const customBizhiUrls = reactive([]) as string[];
/** 当前 壁纸Urls */
const bizhiUrls = reactive([]) as string[];

/** 将壁纸数据 添加到本地 */
const setBizhiDataToLocal = async (
  openIndex: number | null,
  systemUrls: string[] | null,
  customUrls: string[] | null
) => {
  // 壁纸数据
  let dataStr = await wxt.storage.getItem(`local:${BizhiDataMark}`) as string | null;
  let data = { openIndex: 0, systemUrls: [], customUrls: [] } as BizhiDataType; // 默认数据
  // 数据是否 存在
  let dataStatus = false; // 默认：不存在
  // 判断 本地是否存在 壁纸数据
  if (dataStr) {
    // 存在
    dataStatus = true;
    // 对数据进行转换，如果转换报错，则当作数据不存在进行处理
    try {
      data = JSON.parse(dataStr);
    } catch (error) {
      dataStatus = false;
    }
  }
  /** 根据所给参数，给数据进行赋值 */
  if (openIndex) {
    data.openIndex = openIndex;
  }
  if (systemUrls?.length) {
    data.systemUrls = systemUrls;
  }
  if (customUrls?.length) {
    data.customUrls = customUrls;
  }
  await wxt.storage.setItem(`local:${BizhiDataMark}`, JSON.stringify(data));
};

/** 方法 */
/** 获取public中壁纸文件资源 将其遍历，并添加到 systemBizhiUrls 集合中 */
const setSystemBizhiUrls = async () => {
  // 将未设置壁纸时的默认壁纸，添加到systemUrls集合中，并且必须在最开始进行添加（否则，出现壁纸与设置不符）
  systemBizhiUrls.push(defaultBgUrl);
  
  // 获取 bizhi 下所有 png/jpg 文件
  const bizhiImageFiles = import.meta.glob("/public/images/bizhi/*.(png|jpg)");
  // console.log(bizhiImageFiles);
  // 遍历文件路径
  if (bizhiImageFiles) {
    Object.keys(bizhiImageFiles).forEach(async (filePath) => {
      // console.log(filePath); // 输出资源 URL
      const fileName = filePath.split("/")[filePath.split("/").length - 1];
      systemBizhiUrls.push(`${bizhiUrlPrefix}/${fileName}`);
    });
  }
  // 将数据存放到本地
  await setBizhiDataToLocal(null, systemBizhiUrls, null);
};

/** 初始化 壁纸数据 */
const initBizhiData = async() => {
  /** 获取本地 壁纸数据 */
  const bizhiData = await wxt.storage.getItem(`local:${BizhiDataMark}`) as string | null;
  /** 获取 public 中所有壁纸文件 */
  // 如果 本地不存在 壁纸数据，则调用setSystemBizhiUrls方法设置 systemBizhiUrls 数据
  if (!bizhiData) {
    await setSystemBizhiUrls();
  } else {
    // 存在壁纸数据，将数据转换为 对象格式，遍历将其添加到systemBizhiUrls集合中
    try {
      const temp = JSON.parse(bizhiData) as BizhiDataType;
      // 如果 当前壁纸数据存在，则将当前壁纸url的值，全部清除
      if (systemBizhiUrls.length) {
        for (let i = 0; i < systemBizhiUrls.length; i++) {
          systemBizhiUrls.pop();
        }
      }
      // 对其赋值
      temp.systemUrls.forEach((item) => {
        systemBizhiUrls.push(item);
      });
    } catch (error) {
      // 转换出现错误，则通过 调用setSystemBizhiUrls方法设置 systemBizhiUrls 数据
      setSystemBizhiUrls();
    }
  }
  /** 获取自定义 壁纸url */
  // 如果存在 自定义壁纸，则获取自定义壁纸url集合
  if (bizhiData) {
    // 存在壁纸数据，将数据转换为 对象格式，遍历将其添加到customBizhiUrls集合中
    try {
      const temp = JSON.parse(bizhiData) as BizhiDataType;
      // 如果 当前壁纸数据存在，则将当前壁纸url的值，全部清除
      if (customBizhiUrls.length) {
        for (let i = 0; i < customBizhiUrls.length; i++) {
          customBizhiUrls.pop();
        }
      }
      // 对其赋值
      temp.customUrls.forEach((item) => {
        customBizhiUrls.push(item);
      });
    } catch (error) {
      console.error("获取自定义壁纸时，对壁纸数据进行转换时，出现报错\n" + error);
    }
  }
  /**
   * 合并 当前系统壁纸url 和 自定义url
   */
  let bizhiUrlsTemp = [...systemBizhiUrls, ...customBizhiUrls];
  bizhiUrlsTemp.forEach((item) => {
    bizhiUrls.push(item);
  });

  // 同步 上次选中的 壁纸
  if(bizhiData) {
    try {
      const temp = JSON.parse(bizhiData) as BizhiDataType;
      // 如果 当前壁纸数据存在，则将同步上次壁纸的索引
      if(temp) {
        bizhiIndex.value = temp.openIndex ?? 0;
        bizhiUrl.value = bizhiUrls[bizhiIndex.value];
        // 设置 当前背景图
        sendMessage("setBackgroundUrl", { url: bizhiUrl.value });
      }
    }
    catch(error) {
      console.log("同步壁纸索引时，对壁纸数据转换时出错\n", error)
    }
  }
};

/**
 * 选中当前背景图
 */
const selectBizhiImage = async() => {
  bizhiUrl.value = bizhiUrls[bizhiIndex.value];
  // 将壁纸数据 存放到本地
  await setBizhiDataToLocal(bizhiIndex.value, null, null);
  // 设置 当前背景图
  sendMessage("setBackgroundUrl", { url: bizhiUrl.value });
};

/** 切换swiper */
const onChange = (current: number, prev: number) => {
  // console.log(current);
  bizhiIndex.value = current;
};

/** 监听 esc 键 隐藏当前组件 */
const handleKeyup = (event: KeyboardEvent) => {
  // console.log(event.key);
  const key = event.key.toLocaleLowerCase();
  if (key === "escape") {
    // 如果没有在预览，则 将壁纸组件 隐藏
    if (!bizhiPreviewStatus.value) {
      showBizhiSwiper.value = false;
      bizhiPreviewStatus.value = false;
    } else {
      // 由于开启了 按esc可关闭预览，所以当之前开启了预览，则再次按esc时，会自动关闭预览
      bizhiPreviewStatus.value = false;
    }
  }
};

onMounted(async() => {
  /** 获取壁纸数据 */
  await initBizhiData();
  // 监听 keyup 事件
  window.addEventListener("keyup", handleKeyup);
});
onUnmounted(() => {
  // 移除 keyup 事件
  window.removeEventListener("keyup", handleKeyup);
});
</script>

<template>
  <div>
    <AddRemoveList>
      <div class="swiper-container" v-if="showBizhiSwiper">
        <!-- 壁纸swiper -->
        <el-carousel
          height="220px"
          :autoplay="false"
          trigger="click"
          @change="onChange"
        >
          <!-- 自定义指示器 -->
          <div class="swiper-dot">
            <div>
              <div class="index">
                {{ bizhiIndex + 1 }} / {{ bizhiUrls.length }}
              </div>
              <el-button type="primary" size="small" @click="selectBizhiImage">
                启用
              </el-button>
            </div>
          </div>
          <template v-for="(item, index) in bizhiUrls" :key="item + index">
            <el-carousel-item>
              <el-image
                style="width: 100%; height: 100%"
                :src="convartBgURL(item)"
                fit="cover"
                :preview-src-list="[convartBgURL(item)]"
                :hide-on-click-modal="false"
                :preview-teleported="true"
                @click="bizhiPreviewStatus = true"
              />
            </el-carousel-item>
          </template>
        </el-carousel>
      </div>
      <div class="affix" @click="showBizhiSwiper = !showBizhiSwiper">
        <el-icon><Camera /></el-icon>
      </div>
    </AddRemoveList>
  </div>
</template>

<!-- 局部样式 -->
<style scoped lang="less">
.swiper-container {
  position: fixed;
  top: 20px;
  left: calc(50% - 260px);
  width: 520px;
  border-radius: 5px;
  overflow: hidden;
  transition: 1s;

  &:hover {
    box-shadow: 0px 0px 10px 1px white;
  }
}

.swiper-dot {
  position: absolute;
  bottom: 0px;
  left: 0px;
  width: 100%;
  height: 36px;
  display: flex;
  align-items: center;
  z-index: 1;
  background: rgba(255, 255, 255, 0.5);

  > div {
    flex: 1;
    padding: 0px 5px;
    display: flex;
    justify-content: space-between;
    align-items: center;

    .index {
      padding: 2px 6px;
      border-radius: 10px;
      background: rgba(255, 255, 255, 0.9);
    }
  }
}

.affix {
  position: fixed;
  top: 20px;
  right: 20px;
  width: 50px;
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  transition: 0.5s;
  transform: rotate(180deg);

  &:hover {
    cursor: pointer;
    color: #409eff;
    background: white;
    border-radius: 50%;
    transition: 0.8s;
    transform: rotate(0deg);
  }
}
</style>
